package com.ldk.api.handler;

import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.ldk.api.ApiVersion;
import com.ldk.api.CheckToken;
import com.ldk.api.Consts;
import com.ldk.api.ErrorCode;
import com.ldk.api.RequestPlatform;
import com.ldk.api.ResponseObject;
import com.ldk.api.ResponseResult;
import com.ldk.base.framework.util.ConvertUtil;
import com.ldk.base.framework.util.SystemUtil;
import com.ldk.framework.entity.Driver;
import com.ldk.framework.entity.SFCServiceOtherConfig;
import com.ldk.framework.entity.ServiceConfig;
import com.ldk.framework.entity.ServiceTrip;
import com.ldk.framework.entity.User;
import com.ldk.framework.enums.BillingMode;
import com.ldk.framework.enums.DriverStatus;
import com.ldk.framework.enums.PlatformUserType;
import com.ldk.framework.enums.TripNoType;
import com.ldk.framework.enums.ServiceCode;
import com.ldk.framework.enums.TripStatus;
import com.ldk.framework.service.IDriverService;
import com.ldk.framework.service.ISFCServiceTripService;
import com.ldk.framework.service.IServiceConfigService;
import com.ldk.framework.service.IServiceTripCrewsService;
import com.ldk.framework.service.ITenpayService;
import com.ldk.framework.service.IUserService;

/**
 * 顺风车业务模块
 * @author xiangwl
 * 2017年3月4日
 * com.ldk.api.handler
 * SFCRequestHandler
 */
public class SFCRequestHandler extends BZBaseRequestHandler {

	/**
	 * 顺丰车业务流程
	 * 用户端：1、发布行程 2、取消行程 3、支付行程 4、评价行程 5投诉行程
	 * 司机端：1、发布行程 2、接受行程 3、拒绝星系 4、确认用户上车 5、已发车 6结束行程
	 */
	@Autowired
	private IServiceConfigService serviceConfigService;
	@Autowired
	private IUserService userService;
	@Autowired
	private IDriverService driverService;
	@Autowired
	private ISFCServiceTripService sfcServiceTripService;
	@Autowired
	private IServiceTripCrewsService serviceTripCrewsService;
	@Autowired
	private ITenpayService tenpayService;
	
	/**
	 * 用户发布顺风车行程
	 * @param parms
	 * @paramopenId 用户openId
	 * @paramstartLocation 出发地点
	 * @paramstartLon 出发地点经度
	 * @paramstartLat 出发地点纬度
	 * @paramendLocation 目的地点
	 * @paramendLon 目的地点经度
	 * @paramendLat 目的地点纬度
	 * @paramgoTime 出发时间 时间字符串yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	@ApiVersion(value={1})
	@CheckToken(tokenKey="openId",platform=RequestPlatform.client)
	public ResponseObject userPublish(Map<String, Object> parms){
		logger.error("ycs sfc userPublish:");

		ResponseObject response = ResponseResult.create("sfc", "userPublish");
		//参数检验
		if(!checkRequireParms(parms, "openId", "startLocation", "startLon", "startLat",
				             "endLocation", "endLon", "endLat", "goTime"))
		{
			return ResponseResult.exception(response, ErrorCode.REQUEST_PARMS_ERROR);
		}
		String openId = ConvertUtil.parseString(parms.get("openId"));
		String startLocation = ConvertUtil.parseString(parms.get("startLocation"));
		Double startLon = ConvertUtil.parseDouble(parms.get("startLon"));
		Double startLat = ConvertUtil.parseDouble(parms.get("startLat"));
		String endLocation = ConvertUtil.parseString(parms.get("endLocation"));
		Double endLon = ConvertUtil.parseDouble(parms.get("endLon"));
		Double endLat = ConvertUtil.parseDouble(parms.get("endLat"));
		String goTime = ConvertUtil.parseString(parms.get("goTime"));
		if(StringUtils.isBlank(openId)){
			return ResponseResult.exception(response, ErrorCode.OPENID_EMPTY);
		}
		User user = userService.getUserByOpenId("", openId);
		if(user == null){
			return ResponseResult.exception(response, ErrorCode.USER_NOT_EXIST);
		}
		//判断用户是否已经有了未完成的包车行程
		int status = TripStatus.Publish.getValue()
				//| TripStatus.DepositPayed.getValue()
				| TripStatus.Accept.getValue()
				| TripStatus.Refuse.getValue()
				| TripStatus.Payed.getValue()
				| TripStatus.OnTheCar.getValue()
				| TripStatus.WaitingPerson.getValue()
				| TripStatus.Go.getValue();
		ServiceTrip query = new ServiceTrip();
		query.setServiceCode(ServiceCode.SFC.getCode());
		query.setOpenId(openId);
		query.setStatus(status);
		
		long count = sfcServiceTripService.selectCount("", query);
		if(count > 0){
			return ResponseResult.exception(response, ErrorCode.SFC_HAS_NOT_FINISHED_TRIP);
		}
		//出发地点为空
		if(StringUtils.isBlank(startLocation) ||
		   startLon == null || startLon == 0 ||
		   startLat == null || startLat == 0){
			return ResponseResult.exception(response, ErrorCode.SFC_START_EMPTY);
		}
		//目的地点为空
		if(StringUtils.isBlank(endLocation) ||
		   endLon == null || endLon == 0 ||
		   endLat == null || endLat == 0){
			return ResponseResult.exception(response, ErrorCode.SFC_END_EMPTY);
		}
		//出发时间为空
		if(StringUtils.isBlank(goTime)){
			return ResponseResult.exception(response, ErrorCode.SFC_GO_TIME_EMPTY);
		}
		Map<String, Object> result = sfcServiceTripService.estimateFee("", ServiceCode.SFC.getCode(), "" , 0L, startLon, startLat, endLon, endLat, 0, Consts.BAIDU_MAP_AK, Consts.AREA_CODE);
		Boolean success = result.containsKey("success") ? ConvertUtil.parseBoolean(result.get("success")) : false;
		if(!success){
			return ResponseResult.exception(response, ErrorCode.TRIP_READ_CONFIG_FAILED);
		}
		//转化为
		double distance = result.containsKey("distance") ? ConvertUtil.parseDouble(result.get("distance")) : 0.0;//米
		double duration = result.containsKey("duration") ? ConvertUtil.parseDouble(result.get("duration")) : 0.0;//秒
		//总费用
		double totalFee = result.containsKey("fee") ? ConvertUtil.parseDouble(result.get("fee")) : 0.0;
		
		//剩余部分费用
		//double payFee = 0.0;
		//计算定金
		//double depositPayFee = 0.0;
		
		ServiceConfig configQuery = new ServiceConfig();
		configQuery.setServiceCode(ServiceCode.SFC.getCode());
		configQuery.setEnabled(true);
		
		ServiceConfig config = serviceConfigService.selectOne("", configQuery);
		SFCServiceOtherConfig sfcConfig = new SFCServiceOtherConfig();
		/*if(config != null && !StringUtils.isBlank(config.getOtherConfig())){
			sfcConfig = JSON.parseObject(config.getOtherConfig(), SFCServiceOtherConfig.class);
			
		}*/
		if(sfcConfig == null){
			return ResponseResult.exception(response, ErrorCode.TRIP_READ_CONFIG_FAILED);
		}
		//计算定金
		//depositPayFee = sfcConfig.getPayDepositRatio() * totalFee / 100;
		//payFee = totalFee - depositPayFee;
		
		String tripNo = SystemUtil.generateOrderNo(TripNoType.SFC.getPrefix());
		try{
			Long lGoTime = SystemUtil.stringToSeconds(goTime, "yyyy-MM-dd HH:mm:ss");
			ServiceTrip entity = new ServiceTrip();
			entity.setTripNo(tripNo);
			entity.setServiceCode(ServiceCode.SFC.getCode());
			entity.setUserType(PlatformUserType.CLIENT_USER.getValue());
			entity.setOpenId(openId);
			entity.setRoadId(0L);
			entity.setStartLocation(startLocation);
			entity.setStartLon(startLon);
			entity.setStartLat(startLat);
			entity.setEndLocation(endLocation);
			entity.setEndLon(endLon);
			entity.setEndLat(endLat);
			entity.setGoTime(lGoTime);
			entity.setCarRank("");
			entity.setCarSeats(0);//废弃
			entity.setCrewCount(1);
			entity.setCreateTime(SystemUtil.getAllSeconds());
			entity.setStatus(TripStatus.Publish.getValue());
			//单位米
			entity.setDistance(distance);
			//单位秒
			entity.setDuration(duration);
			entity.setHasAsign(false);
			entity.setHasComment(false);
			entity.setBillingMode(BillingMode.Distance.getValue());
			//对费用进行四舍五入
			//double tmpPayFee = ConvertUtil.toRoundFiexd(payFee);
			//double tmpDepositPayFee = ConvertUtil.toRoundFiexd(depositPayFee);
			entity.setPayFee(totalFee);
			//entity.setDepositPayFee(tmpDepositPayFee);
			
			success = sfcServiceTripService.publish("", entity);
		}
		catch(Exception e){
			logger.error(e.getMessage());
		}
		if(success){
			query = new ServiceTrip();
			query.setTripNo(tripNo);
			ServiceTrip trip =  sfcServiceTripService.selectByKey("", query);
			ResponseResult.success(response, trip);
		}
		else{
			ResponseResult.exception(response, ErrorCode.SFC_PUBLISH_ORDER_FAILED);
		}
		
		return response;
	}
	
	/**
	 * 用户取消顺风车行程
	 * @param parms
	 * @paramopenId 用户openId
	 * @paramtripNo 行程单号
	 * @return
	 */
	@ApiVersion(value={1})
	@CheckToken(tokenKey="openId",platform=RequestPlatform.client)
	public ResponseObject userCancel(Map<String, Object> parms){
		ResponseObject response = ResponseResult.create("sfc", "userCancel");
		//参数检验
		if(!checkRequireParms(parms, "openId", "tripNo")){
			return ResponseResult.exception(response, ErrorCode.REQUEST_PARMS_ERROR);
		}
		String openId = ConvertUtil.parseString(parms.get("openId"));
		String tripNo = ConvertUtil.parseString(parms.get("tripNo"));
		if(StringUtils.isBlank(openId)){
			return ResponseResult.exception(response, ErrorCode.OPENID_EMPTY);
		}
		if(StringUtils.isBlank(tripNo)){
			return ResponseResult.exception(response, ErrorCode.TRIP_NO_EMPTY);
		}
		User user = userService.getUserByOpenId("", openId);
		if(user == null){
			return ResponseResult.exception(response, ErrorCode.USER_NOT_EXIST);
		}
		//必须是自己的行程
		ServiceTrip query = new ServiceTrip();
		query.setTripNo(tripNo);
		query.setOpenId(openId);
		query.setServiceCode(ServiceCode.SFC.getCode());
		ServiceTrip trip = sfcServiceTripService.selectOne("", query);
		if(trip == null){
			return ResponseResult.exception(response, ErrorCode.TRIP_NOT_EXIST);
		}
		int tripStatus = TripStatus.Publish.getValue()
				//+ TripStatus.DepositPayed.getValue()
				+ TripStatus.Accept.getValue() + TripStatus.Refuse.getValue()
				+ TripStatus.Payed.getValue() + TripStatus.WaitingPerson.getValue()
				+ TripStatus.OnTheCar.getValue();
		//能取消的行程状态值(发布，接单，上车)
		if ((trip.getStatus() & tripStatus) != trip.getStatus()) {
			return ResponseResult.exception(response,ErrorCode.STATUS_ERROR);
		}
		//获取包车的配置信息
		ServiceConfig configQuery = new ServiceConfig();
		configQuery.setServiceCode(ServiceCode.BC.getCode());
		configQuery.setEnabled(true);
		ServiceConfig config = serviceConfigService.selectOne("", configQuery);
		SFCServiceOtherConfig sfcConfig = new SFCServiceOtherConfig(); 
		int dayCancelTimes = 3;//默认3天
		/*if(config != null && !StringUtils.isBlank(config.getOtherConfig())){
			sfcConfig = JSON.parseObject(config.getOtherConfig(), SFCServiceOtherConfig.class);
			dayCancelTimes = sfcConfig.getUserDayCancelTimes() == null ? 3 :  sfcConfig.getUserDayCancelTimes();
		}*/
		query = new ServiceTrip();
		query.setOpenId(openId);
		query.setServiceCode(ServiceCode.BC.getCode());
		query.setUserType(PlatformUserType.CLIENT_USER.getValue());
		query.setStatus(TripStatus.UserCancel.getValue());
		long startTime = SystemUtil.getAllDays() * 24 * 3600;
		long endTime = startTime + (24 * 3600);
		query.setStartTime(startTime);
		query.setEndTime(endTime);
		
		long userDayCancelTime = sfcServiceTripService.getDayCancelCount("", query);
		if(userDayCancelTime >= dayCancelTimes){
			return ResponseResult.exception(response,ErrorCode.BC_OVER_MAX_CANCEL_TIMES);
		}
		
		Boolean success = false;
		try{
			success = sfcServiceTripService.userCancel("", trip, user);
			
		}catch(Exception e){
			logger.error(e.getMessage());
		}
		if(success){
			query = new ServiceTrip();
			query.setTripNo(tripNo);
			ServiceTrip result = sfcServiceTripService.selectOne("", query);
			
			response = ResponseResult.success(response, result);
		}
		else{
			response = ResponseResult.exception(response, ErrorCode.SFC_USER_CANCEL_TRIP_FAILED);
		}
		
		return response;
	}
	
	/**
	 * 司机接受顺风车行程
	 * @param parms
	 * @paramopenId 司机openId
	 * @paramtripNo 用户行程号
	 * @return
	 */
	@ApiVersion(value={1})
	@CheckToken(tokenKey="openId",platform=RequestPlatform.driver)
	public ResponseObject driverAccept(Map<String, Object> parms){
		ResponseObject response = ResponseResult.create("sfc", "driverAccept");
		//参数检验
		if(!checkRequireParms(parms, "openId", "tripNo")){
			return ResponseResult.exception(response, ErrorCode.REQUEST_PARMS_ERROR);
		}
		String  openId = ConvertUtil.parseString(parms.get("openId"));
		String  tripNo = ConvertUtil.parseString(parms.get("tripNo"));
		if (StringUtils.isBlank(openId)) {
			return ResponseResult.exception(response, ErrorCode.OPENID_EMPTY);
		}
		if (StringUtils.isBlank(tripNo)) {
			return ResponseResult.exception(response, ErrorCode.TRIP_NO_EMPTY);
		}
		//判断司机是否存在
		Driver driver = driverService.getDriverByOpenId("", openId);
		if (driver == null) {
			return ResponseResult.exception(response, ErrorCode.DRIVER_NOT_EXIST);
		}
		//接行程的司机状态条件
		if(driver.getStatus() != DriverStatus.OnLine.getValue()){
			return ResponseResult.exception(response, ErrorCode.DRIVER_STATUS_NOT_ONLINE);
		}
		//判断司机是否有发布的顺风车行程
		ServiceTrip driverTripQuery = new ServiceTrip();
		driverTripQuery.setOpenId(openId);
		driverTripQuery.setStatus(TripStatus.Publish.getValue());
		driverTripQuery.setServiceCode(ServiceCode.SFC.getCode());
		driverTripQuery.setUserType(PlatformUserType.DRIVER_USER.getValue());
		ServiceTrip driverTrip = sfcServiceTripService.selectOne("", driverTripQuery);
		
		if(driverTrip == null){
			return ResponseResult.exception(response, ErrorCode.TRIP_NOT_EXIST);
		}
		//判断行程的乘客数是否大于最大座位数-1（－1表示司机也是一个位置）
		int crewCount = driverTrip.getCrewCount() == null ? 0 : driverTrip.getCrewCount();
		int carSeats = driverTrip.getCarSeats() == null ? 0 : driverTrip.getCarSeats();
		//已经超载乘客数
		if(crewCount + 2 > carSeats){
			return ResponseResult.exception(response, ErrorCode.SFC_TRIP_CREWS_FULL);
		}
		//用户行程必须存在
		ServiceTrip userTripQuery = new ServiceTrip();
		userTripQuery.setTripNo(tripNo);
		userTripQuery.setUserType(PlatformUserType.CLIENT_USER.getValue());
		userTripQuery.setServiceCode(ServiceCode.SFC.getCode());
		ServiceTrip userTrip = sfcServiceTripService.selectOne("", userTripQuery);
		if (userTrip == null) {
			return ResponseResult.exception(response, ErrorCode.TRIP_NOT_EXIST);
		}
		// 能接收的行程状态值(定金支付)
		/*if (userTrip.getStatus() != TripStatus.DepositPayed.getValue()) {
			return ResponseResult.exception(response, ErrorCode.STATUS_ERROR);
		}*/
		if (userTrip.getStatus() != TripStatus.Publish.getValue()) {
			return ResponseResult.exception(response, ErrorCode.STATUS_ERROR);
		}
		Boolean success = false;
		try{
			success = sfcServiceTripService.driverAccept("", driverTrip, userTrip);
		}
		catch(Exception e){
			logger.error(e.getMessage());
		}
		if(success){
			response = ResponseResult.success(response, userTrip);
		}
		else{
			response = ResponseResult.exception(response, ErrorCode.SFC_DRIVER_ACCEPT_FAILED);
		}
		
		return response;
	}
}
